package com.qinggeng.project.api.websocket;

import com.alibaba.fastjson.JSONObject;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.common.utils.spring.SpringUtils;
import com.qinggeng.framework.config.mq.MQSendUtils;
import com.qinggeng.framework.config.mq.dto.MessageBulletChatDTO;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.framework.redis.RedisCache;
import com.qinggeng.framework.web.domain.AjaxResult;
import com.qinggeng.project.api.websocket.model.MessageModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 吴鹏飞
 * @date 2020/11/16
 * WebSocketServer类
 */
@Slf4j
@ServerEndpoint("/websocket/bulletchat/{userId}/{token}")
@Component
public class AppWebSocketServer {


    private static final String KEY = "api_login_tokens:";

    private final RedisCache redisCache = SpringUtils.getBean(RedisCache.class);

    private final MQSendUtils mqSendUtils = SpringUtils.getBean(MQSendUtils.class);

    private final  String OK="ok";

    private static final Map<String, Session> map = new ConcurrentHashMap();


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen

    public void onOpen(Session session, @PathParam("userId") String userId, @PathParam("token") String token) {
        System.out.println("连接成功");
        log.info("userId {},token {}", userId, token);
        if(map.size()>=1000){
            return;
        }
        try {
            String redisKey = KEY + token;
            boolean bl = redisCache.hasKey(redisKey);
            if (bl) {
                //封装参数
                map.put(userId, session);
                return;
            }
            if (!session.isOpen()) {
                session.close();
            }
        } catch (Exception e) {

        }

    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("userId") String userId) {
        try {
            if (StringUtils.isNotEmpty(message)) {
                MessageModel messageModel = JSONObject.parseObject(message, MessageModel.class);
                String type = messageModel.getType();
                if (StringUtils.isNotEmpty(type)) {
                    switch (type) {
                        case "2":
                            MessageBulletChatDTO messageBulletChatDTO=new MessageBulletChatDTO();
                            messageBulletChatDTO.setUserId(Long.valueOf(userId));
                            Integer mqType=Integer.valueOf(MQTypeEnum.INDEX_BULLET_CHAT.getType());
                            messageBulletChatDTO.setType(mqType);
                            mqSendUtils.sendAsynMessage(messageBulletChatDTO);
                            break;
                        default:

                    }
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId) {

        try {

            Session session = map.remove(userId);
            if (null != session || session.isOpen()) {
                log.info("连接关闭,userId={}", userId);
                session.close();
            }
        } catch (Exception e) {
            log.info("websocket异常 ,userId={} 退出 ", userId);
        }

    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public AjaxResult onError(Session session, Throwable error) {
//        log.error("发生错误，error{}", error.getMessage());
        return AjaxResult.error("发生错误");
    }

    //群发自定义消息
    public static void massHair(MessageModel messageModel) {
        for (Map.Entry<String, Session> entry : map.entrySet()) {
            if (!messageModel.getUserId().equals(entry.getKey())) {
                Session session = entry.getValue();
                if (session.isOpen()) {
                    try {
                        String message = JSONObject.toJSONString(messageModel);
                        session.getBasicRemote().sendText(message);
                    } catch (Exception e) {
                        continue;
                    }
                }
            }
        }
    }
}

